package com.tanhua.server.serivce;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.tanhua.commons.utils.Constants;
import com.tanhua.dubbo.api.*;
import com.tanhua.model.db.Question;
import com.tanhua.model.db.Settings;
import com.tanhua.model.db.User;
import com.tanhua.model.db.UserInfo;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.SettingsVo;
import com.tanhua.model.vo.UserInfoVo;
import com.tanhua.model.vo.UserLikeListVo;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class UsersService {

    @DubboReference
    private UserInfoApi userInfoApi;

    @DubboReference
    private QuestionApi questionApi;

    @DubboReference
    private SettingsApi settingsApi;

    @DubboReference
    private BlackListApi blackListApi;

    @DubboReference
    private UserApi userApi;

    //根据用户id，查询用户资料
    public UserInfoVo findUserInfoById(Long userId) {
        //1、调用API查询
        UserInfo userInfo = userInfoApi.findById(userId);
        //2、转化为VO
        UserInfoVo vo = new UserInfoVo();
        //工具类转化
        BeanUtils.copyProperties(userInfo,vo); //将UserInfo中同名，同类型的属性，自动赋值到vo中
        //不同的，单独处理
        if(userInfo.getAge() != null) {
            vo.setAge(userInfo.getAge().toString());
        }
        return vo;
    }

    //更新
    public void updateUserInfo(UserInfo info) {
        userInfoApi.update(info);
    }

    //查询通用设置
    public SettingsVo settings() {
        SettingsVo vo = new SettingsVo();
        //设置id和手机号码
        vo.setId(UserHolder.getUserId());
        vo.setPhone(UserHolder.getMobile());
        //查询并设置陌生人问题
        //根据当前用户id，查询陌生人问题
        Question question = questionApi.findByUserId(UserHolder.getUserId());
        vo.setStrangerQuestion(question == null ? "你喜欢JAVA吗？":question.getTxt());
        //查询并设置通知开关
        //根据当前用户id，查询通知开关
        Settings settings = settingsApi.findByUserId(UserHolder.getUserId());
        if(settings!=null) {
            vo.setPinglunNotification(settings.getPinglunNotification());
            vo.setLikeNotification(settings.getLikeNotification());
            vo.setGonggaoNotification(settings.getGonggaoNotification());
        }
        return vo;
    }

    //设置陌生人问题(保存或者更新)
    public void questions(String content) {
        //1、获取当前用户id
        Long userId = UserHolder.getUserId();
        //2、根据用户id，查询陌生人问题
        Question question = questionApi.findByUserId(userId);
        //3、如果问题存在，更新
        if(question != null) {
            question.setTxt(content);
            questionApi.update(question);
        }else {
            //4、问题不存在，保存
            question = new Question();
            question.setTxt(content);
            question.setUserId(userId);
            questionApi.save(question);
        }
    }

    //设置通知开关(保存或者更新)
    public void setting(Map map) {
        Boolean like = (Boolean) map.get("likeNotification");
        Boolean pingl = (Boolean) map.get("pinglunNotification");
        Boolean gongg = (Boolean) map.get("gonggaoNotification");
        //1、获取当前用户id
        Long userId = UserHolder.getUserId();
        //2、根据用户id，查询当前用户的通知设置
        Settings settings = settingsApi.findByUserId(userId);
        //3、如果数据存在，更新
        if(settings != null) {
            settings.setGonggaoNotification(gongg);
            settings.setPinglunNotification(pingl);
            settings.setLikeNotification(like);
            settingsApi.update(settings);
        }else {
            //4、如果数据不存在，保存
            settings = new Settings();
            settings.setUserId(userId);
            settings.setGonggaoNotification(gongg);
            settings.setPinglunNotification(pingl);
            settings.setLikeNotification(like);
            settingsApi.save(settings);
        }
    }

    //分页查询黑名单数据
    public PageResult blacklist(Integer page, Integer pagesize) {
        //1、获取当前用户id
        Long userId = UserHolder.getUserId();
        //2、调用API分页查询数据：IPage
        IPage iPage = blackListApi.findByUserId(page,pagesize,userId);
        //3、将IPage中的数据内容，设置到PageResult
        PageResult vo = new PageResult(page,pagesize,
                iPage.getTotal(),iPage.getRecords());
        //4、返回
        return vo;
    }

    //删除=黑名单:根据当前用户userId和黑名单用户blackUserId
    public void delBlacklist(Long blackUserId) {
        //1、获取当前用户id
        Long userId = UserHolder.getUserId();
        //2、调用api删除
        blackListApi.delete(userId,blackUserId);
    }

    @DubboReference
    private VisitorsApi visitorsApi;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    /**
     *  互相喜欢、喜欢、粉丝、谁看过我 - 分页列表
     *  type
     *      1 互相关注
     *      2 我关注
     *      3 粉丝
     *      4 谁看过我
     */
    public PageResult friends(Integer type, Integer page, Integer pagesize) {
        if(type != 4) {
            return new PageResult(); //实战完成
        }
        Long userId = UserHolder.getUserId();
        //调用API，根据用户id，分页查询访客列表  List<visitors>
        List<Visitors> list = visitorsApi.findAll(userId,page,pagesize);
        if(CollUtil.isEmpty(list)) {
            return new PageResult();
        }
        //提取所有的访客人信息
        List<Long> userIds = CollUtil.getFieldValues(list, "visitorUserId", Long.class);
        Map<Long, UserInfo> map = userInfoApi.findByIds(userIds);
        //将List<visitors>转成 List<UserLikeListVo>
        List<UserLikeListVo> vos = new ArrayList<>();
        for (Visitors visitors : list) {
            UserInfo userInfo = map.get(visitors.getVisitorUserId());
            UserLikeListVo vo = UserLikeListVo.init(userInfo, visitors);
            vos.add(vo);
        }
        //设置查看历史访客的时间
        String key = Constants.VISITORS_USER + userId;
        Long value = System.currentTimeMillis();
        redisTemplate.opsForValue().set(key,value.toString());
        //构造返回
        return new PageResult(page,pagesize,0l,vos);
    }

    public void sendVerificationCode(Long userId) {
        String phone = userApi.findPhoneById(userId);
        String code = "123456";
        //3、调用SmsTemplate对象，发送验证码
        //smsTemplate.sendSms(phone,code);
        //4、将验证码存入到Redis中
        redisTemplate.opsForValue().set("UPCODE_"+phone,code,5, TimeUnit.MINUTES);
    }

    public Boolean checkVerificationCode(String verificationCode) {
        Long userId = UserHolder.getUserId();
        String phone = userApi.findPhoneById(userId);
        String code = redisTemplate.opsForValue().get("UPCODE_" + phone);
        //1.2 判断redis中的验证码是否存在，和用户输入的是否一致
        if(StringUtils.isEmpty(code) || !code.equals(verificationCode)) {
            //1.3 redis验证码不存在或者和输入的不一致。验证码
            //抛出异常
            return false;
        }else {
            //1.4 如果一致，删除验证码
            redisTemplate.delete("CODE_" + phone);
            return true;
        }
    }

    public void phone(String phone) {
        User user = userApi.findById(UserHolder.getUserId());
        user.setMobile(phone);
        userApi.update(user);
    }
}
